//auther cjh
package cn.agiledata.bank.common.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.PageBean;
import cn.agiledata.bank.common.util.StringUtil;
import com.vnv.infrastructure.logic.IPBAppFactory;

public abstract class HqlPageListTemplate extends HibernateDaoSupport implements
        PageList, HibernatePageBean {

    // 拼写Hql
    public abstract String getHql();

    // 参数Map
    public abstract Map getParams();

    // 起始页
    public abstract String getStartPage();

    // 每页多少条数据
    public abstract String getPageRecord();

    // 是否需要取total
    public boolean isNeedTotal() {
        return true;
    }

    // 是否需要取list
    public boolean isNeedList() {
        return true;
    }

    // 如果需要total,则count为传递进来的值
    public int needTotalCount() {
        return 0;
    }

    public PageBean getAccountListPageBean() {

        this.setSessionFactory((SessionFactory) IPBAppFactory
                .getObj("sessionFactory"));
        PageBean pb = null;
        if (isNeedTotal()) { // 如果需要取total

            pb = new PageBean(
                    getPageCount(),
                    getFirst(),
                    Integer
                            .parseInt(StringUtil.isStrEmpty(getPageRecord()) ? Constant.PAGESIZE
                                    .toString()
                                    : getPageRecord()));

        } else { // 如果不需要取total
            pb = new PageBean(
                    needTotalCount(),
                    getFirst(),
                    Integer
                            .parseInt(StringUtil.isStrEmpty(getPageRecord()) ? Constant.PAGESIZE
                                    .toString()
                                    : getPageRecord()));
        }
        if (isNeedList()) { // 如果需要取List
            pb.setData(getPageList());
        } else {
            pb.setData(new ArrayList());
        }
        return pb;
    }

    /**
     * 得到起始页
     * 
     * @return
     */
    public int getFirst() {
        String startPage = getStartPage();
        int startPageNo = 1;
        if (startPage != null && !startPage.equals("")) {
            startPageNo = Integer.parseInt(startPage);
        }
        return startPageNo;
    }

    /**
     * 得到页面List
     * 
     * @return
     */
    private List getPageList() {
        Query query = this.getQuery(getHql());
        return getList(parsePaging(parseParams(query)));
    }

    /**
     * 得到总共多少条
     * 
     * @return
     */
    private int getPageCount() {
        Query query = this.getQuery(parseCountHql());
        int intCount = getCount(parseParams(query));
        return intCount;
    }

    /**
     * 构造总共多少条数据的Hql语句
     * 
     * @return
     */
    private String parseCountHql() {
        String countHqlPrefix = "select count(*) as count ";
        String filterHql = filterHql();
        return countHqlPrefix + filterHql.substring(0,filterHql.indexOf("order by"));
    }

    /**
     * 过滤
     * 
     * @return
     */
    private String filterHql() {
        String string = getHql();
        int start = string.indexOf("from");
        string = string.substring(start);
        return string;
    }

    /**
     * 从当前session中得到Query接口
     * 
     * @param hql
     * @return
     */
    private Query getQuery(String hql) {
        Session s = null;
        try {
            s = getHibernateTemplate().getSessionFactory().getCurrentSession();
        } catch (Exception e) {
            s = null;
        }
        if (s == null) {
            s = getHibernateTemplate().getSessionFactory().openSession();
        }
        Query q = s.createQuery(hql);
        return q;
    }

    /**
     * 构造参数
     * 
     * @return
     */
    private Query parseParams(Query query) {
        Map map = getParams();
        if (map != null) {
            Set set = map.keySet();
            if (set != null) {
                Iterator iterator = set.iterator();
                while (iterator.hasNext()) {
                    String key = (String) iterator.next();
                    Object value = (Object) map.get(key);
                    if (value instanceof List) {
                        query.setParameterList(key, (Collection) value);
                    } else {
                        query.setParameter(key, value);
                    }
                }
            }
        }
        return query;
    }

    /**
     * 构造分页
     * 
     * @param query
     * @return
     */
    private Query parsePaging(Query query) {
    	if (getStartPage() == null || getPageRecord() == null){
    		return query;
    	}
        int startPage = Integer.parseInt(getStartPage());
        int pageRecord = Integer.parseInt(getPageRecord());
        query.setFirstResult((startPage - 1) * pageRecord);
        // query.setFirstResult(1);
        query.setMaxResults(pageRecord);
        return query;
    }

    /**
     * 得到List
     * 
     * @param query
     * @return
     */
    private List getList(Query query) {
        return query.list();
    }

    /**
     * 得到数据
     * 
     * @param query
     * @return
     */
    private int getCount(Query query) {
        String hql = query.getQueryString();
        if (hql.indexOf(" group by ") < 0) {
            return ((Long) query.uniqueResult()).intValue();
        } else { // 分组查询
            return query.list().size();
        }
    }

}